package com.service.single.example.ldap;


import com.alibaba.fastjson.JSON;
import com.sun.jndi.ldap.LdapCtxFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.filter.EqualsFilter;
import org.springframework.ldap.query.LdapQueryBuilder;
import org.springframework.stereotype.Service;

import javax.naming.Context;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import java.util.Properties;

/**
 * https://www.cnblogs.com/good--luck/p/16697528.html
 * 集成 ldap协议 实现用户认证
 */
@Slf4j
@Service
public class LdapService {

    @Autowired
    private LdapTemplate ldapTemplate;

    /**
     * 实现方法1,集成 spring ldap实现
     * 通过账号密码方式连接 ldap服务，然后检索需要查询的用户
     */
    public void test() {
        // 根据uid 和密码 查询用户是否存在
        EqualsFilter filter = new EqualsFilter("uid", "test1");
        boolean bool = ldapTemplate.authenticate("", filter.toString(), "123456");
        if (bool) {
            // 构建查询条件
            LdapQueryBuilder builder = LdapQueryBuilder.query();
            // 根据 uid查询
            builder.where("uid").is("  test1");
            // 注意person 类，一定要跟 ldap协议中的属性名称对应
            Person person = ldapTemplate.findOne(builder, Person.class);
            System.out.println(JSON.toJSONString(person));
        } else {
            System.out.println("校验失败");
        }
    }

    /**
     * 实现方法1,直接通过账号密码登陆
     * 这种方式兼容 微软AD服务 和 openLdap
     */
    public void test1() {
        String username = "cn=Manager,dc=ricman,dc=localhost";
        String password = "123456";
        String url = "ldap://192.168.10.7:389";

        Properties env = new Properties();
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.INITIAL_CONTEXT_FACTORY, LdapCtxFactory.class.getName());
        env.put(Context.PROVIDER_URL, url);
        env.put(Context.SECURITY_PRINCIPAL, username);
        env.put(Context.SECURITY_CREDENTIALS, password);
        try {
            DirContext ctx = new InitialDirContext(env);
            if (null != ctx) {
                System.out.println("认证成功");
                return;
            }
            System.out.println("认证失败");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * ldaps ssl免密认证,仅适用 微软的AD服务
     */
    public void test2() {
        String username = "admin@test.com";
        String password = "123456";
        String url = "ldaps://192.168.10.7:636";

        System.setProperty("com.sun.jndi.ldap.object.disableEndpointIdentification", "true");
        Properties env = new Properties();
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.INITIAL_CONTEXT_FACTORY, LdapCtxFactory.class.getName());
        env.put(Context.PROVIDER_URL, url);
        env.put(Context.SECURITY_PRINCIPAL, username);
        env.put(Context.SECURITY_CREDENTIALS, password);
        env.put(Context.SECURITY_PROTOCOL, "ssl");
        env.put("java.naming.ldap.factory.socket", DummySSLSocketFactory.class.getName());
        try {
            DirContext ctx = new InitialDirContext(env);
            if (null != ctx) {
                System.out.println("认证成功");
                return;
            }
            System.out.println("认证失败");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
